#ifndef _Persistor_h_
#define _Persistor_h_
#include "Factory/Factory.h"
#include "Persistent.h"			//new users see this first
#include <map>

using namespace common;

namespace persist
{
//class that can read/write objects of type Persistent is
class Persistor : public FactoryHolder
{
protected:
//name of this persistor
	std::string name;
//when reading, want persistents to be unique by record
	typedef std::map<Record, Persistent*> Records;
//when flushing, want records to be unique by persistent
	typedef std::map<Persistent*, Record> Persistents;

	Records records;
	Persistents persistents;
public:
	enum Mode
	{
		WRITE = 1,
		READ,
		EDIT,
	};

	Persistor();
	virtual ~Persistor() {}
//open storage	(stream/file/pipe/whatever it is)
	virtual bool open(const std::string& fname,Persistor::Mode m = READ) =0;
//close storage
	virtual void close()=0;
//clear storage
	virtual void clear()=0;
//flush (e.g. to disk)
	virtual void commit()=0;
//check if open
	virtual bool isOpen()=0;
//check if in READ mode
	virtual bool isReading()=0;
//funnel object in (READ) or out (WRITE)
	virtual void persist(Persistent*& _persistent)=0;
//name of this persistor
	const std::string& getName() const {return  name;}
	std::string& getName(){return name;}
	
//persistents call this when ready to be written/read	
	virtual void load(Persistent* _persistent)=0;
	virtual void save(Persistent* _persistent)=0;
//allocate a chunk of storage for a persistent
	virtual void allocate(Persistent* _persistent)=0;
	virtual void deallocate(Persistent* _persistent)=0;
//allocate a chunk of storage by class identifier and return the given name
	virtual std::string allocate(const Identifier& _id)=0;
	virtual void deallocate(const Identifier& _id)=0;

};

//TODO: persistors manager
	
} //namespace

#endif